package com.tachoknight.geocaching;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.*;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@SuppressWarnings("serial")
public class RoutePlannerServlet extends HttpServlet
{
    private final int MAXIMUM_WAYPOINTS = 25;

    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException
    {
        /* Check that we have a file upload request */
        if (ServletFileUpload.isMultipartContent(req) == false)
        {
            /*
             * Nope, don't have a file, so there's nothing to do (eventually
             * send back to the original html page.
             */

            return;
        }

        List<Waypoint> wayPointsToMap = new ArrayList<Waypoint>();
        /*
         * If we're here, we have a file to process
         */
        try
        {
            ServletFileUpload upload = new ServletFileUpload();
            FileItemIterator iterator = upload.getItemIterator(req);

            while (iterator.hasNext())
            {
                FileItemStream item = iterator.next();
                InputStream stream = item.openStream();

                int len;
                byte[] buffer = new byte[8192];
                String byteFile = "";
                while ((len = stream.read(buffer, 0, buffer.length)) != -1)
                {
                    for (int byteNum = 0; byteNum != buffer.length; ++byteNum)
                    {
                        byteFile += String.valueOf((char) buffer[byteNum]);
                    }
                }
                
                System.out.println("data-> " + byteFile);
                wayPointsToMap = processFile(byteFile);
            }
        }
        catch (FileUploadException e)
        {
            e.printStackTrace();
        }

        /*
         * Okay, now if we have more than two entries in the waypoints array, we
         * can continue.
         */
        if (wayPointsToMap.size() > 1)
        {
            req.setAttribute("waypoints", wayPointsToMap);

            ServletContext sc = getServletContext();
            RequestDispatcher rd = sc.getRequestDispatcher("/directions.jsp");
            try
            {
                rd.forward(req, resp);
            }
            catch (ServletException e)
            {
                e.printStackTrace();
            }
        }
    }

    private List<Waypoint> processFile(String fileContents)
    {
        List<Waypoint> wayPoints = new ArrayList<Waypoint>();

        /*
         * Rules for processing: Each entry on its own line Three columns: Cache
         * name, latitude, longitude separated by three semicolons (;;;) (on the
         * assumption that no cache name has three semicolons in its name :) )
         */
        String[] rows = fileContents.split("\n");

        for (int row = 0; row != rows.length; ++row)
        {
            System.out.println(rows[row]);

            String[] cols = rows[row].split(";;;");

            /* Sanity check... */
            if (rows[row].length() == 0)
                continue;
            
            if (cols.length != 3)
            {
                System.out.println(rows[row] + " could not be parsed properly, so it wasn't added.");
                continue;
            }

            Waypoint waypoint = new Waypoint(cols[0], cols[1], cols[2]);

            /*
             * Google limits the number of points to 25, so we don't want to add
             * any more than that...
             */
            if (row < MAXIMUM_WAYPOINTS)
                wayPoints.add(waypoint);
            else
                System.out.println("Couldn't add " + rows[row]
                                   + " to the list because of the waypoint limit");
        }

        return wayPoints;
    }
}
